MENTAL vs. CÁLCULO
LAMBDA DE CHURCH

Un modelo teórico para las expresiones funcionales

“La mayoría de los lenguajes de programación tienen sus raíces en el cálculo lambda” (Peter Landin)



El Cálculo Lambda, de Church

Conceptos fundamentales

El cálculo lambda o cálculo-λ (lambda calculus o λ-calculus), creado por el matemático, lógico y filósofo Alonzo Church en los años 1930s, es un modelo teórico formal para las expresiones funcionales, es decir, funciones definidas a partir de otras funciones.

Las funciones del cálculo lambda son objetos matemáticos con las siguientes características: Esta distinción se hace necesaria, pues por ejemplo la expresión matemática x+5 no indica si se trata de una función de la variable x o un cálculo con el valor de x. Este problema se resuelve mediante la llamada “notación lambda”. En el caso de una función de una variable, la notación es λx.f(x), en donde: Su aplicación se realiza mediante (λx.f(x))a = f(a) siendo a el argumento. Por ejemplo: (λx.axb)3 = a3b

Para dos variables, la notación es: En general, para n variables, la notación es: La definición de una función recuerda a una expresión cuantificada universalmente, en el que λ desempeña un papel similar a ∀ (para todo).

Los nombres de las variables de las expresiones funcionales es irrelevante. Es por ello que se dice que las variables de la función son ficticias o falsas. Por ejemplo, λxy.x+y y λuv.u+v son equivalentes.


Variables ligadas y libres

En una expresión lambda, una variable x es ligada o libre, según aparezca como parámetro o no, respectivamente, en la definición de la función. Ejemplos:
  1. En la expresión funcional (λx.xy), x es una variable ligada e y es libre.

  2. En la expresión funcional (λxy.xyx), x e y son variables ligadas.

Variables como funciones

Las variables x, y, z,… también se consideran funciones o autofunciones, es decir, que se aplican a sí mismas y se devuelven a sí mismas. En este sentido, la expresión f(x) se suele escribir fx para abreviar, pues se considera que es la aplicación de la función f a la función x. Análogamente, Por ello, una expresión funcional de n variables se suele escribir λx1 ... xn.fx1...xn.


Evaluación parcial

Para toda función lambda de n variables, es posible definir una versión “curry” −nombre que viene del lógico Haskell B. Curry− equivalente, en la que se van aplicando los argumentos en serie, uno tras otro. Por ejemplo, la versión curry de λxyz.xyz es λxyz.xyz. Este proceso se denomina “currificación”. En ambos casos, los argumentos hay que especificarlos en el mismo orden y el resultado es el mismo, pero la sintaxis es distinta: Por lo tanto, en el cálculo lambda, todas las funciones de n parámetros se pueden considerar como una expresión de funciones de un solo parámetro.


Sustitución de variables por argumentos

En la aplicación de una función a unos argumentos, se realiza una sustitución de cada parámetro por su correspondiente argumento. Para indicar esto, el cálculo lambda utiliza la notación [N/x]M, que indica que en la expresión M queremos sustituir la variable x por la expresión N. Ejemplos: Si en M no aparece la variable x, entonces M queda invariable: [N/x]M = M. Por ejemplo, [u/x]y = y.

Evidentemente, por la propia definición de aplicación de función, se tiene que Es la llamada “reducción β”, “conversión β” o “axioma β” del cálculo lambda.

Si la expresión N aparece en M como variable falsa, se le puede asignar un nuevo nombre antes de realizar la sustitución. Por ejemplo: Es la llamada “conversión α” o “axioma α” y se realiza mediante La “conversión η” expresa la idea de que dos funciones f y g son iguales si y solo si dan el mismo resultado para todos los posibles argumentos. Es decir, fa = ga para todo argumento a. Si x no aparece en el cuerpo de f ni el de g, entonces fx = gx.


Cálculos como reducciones

Los cálculos en el cálculo lambda son reducciones sucesivas, aplicando en cada paso la conversión β, hasta que se llega a la forma más simple posible. Una expresión que puede reducirse se denomina “redex” (reduction expresion). Una redex puede contener otras redex. Una expresión que no puede reducirse (que no contiene ningún redex) se dice que se encuentra en “forma normal”.

El teorema de Church-Rosser del cálculo lambda establece que el resultado de un cálculo no depende del orden en el que se aplican las reducciones (sustituciones β), es decir, todas las posibles secuencias de reducciones avanzan hacia el mismo resultado final, que es el mismo que se obtiene cuando se aplican las reducciones de forma concurrente.


Ejemplos de funciones simples
Funciones de orden superior

Si tenemos la expresión de n variables λx1 ... xn.fx1 ... xn Entonces aparecen entonces las funciones de orden superior.

Un ejemplo simple es la composición de dos funciones es λgfx.g(fx). Que es equivalente a gf en notación matemática tradicional (primero se aplica f y luego se aplica g). Por ejemplo: Algunas leyes de composición de funciones son:
Aritmética

Sustituyendo en λx.fx, x por fx, tenemos: λfx.f(fx)

Esta es la definición de una función que, actuando sobre cualquier función fx, produce la misma función iterada dos veces, es decir, f(fx). Esta es la función identificada con el símbolo 2 (en negrita, para diferenciarlo del número 2). Análogamente, Junto con:
En general, un número n en el cálculo lambda es una función que tiene como argumento otra función f y que produce como resultado la n-aria composición de f. Estos números se llaman “numerales de Church”. Ejemplos: Un aspecto sorprendende de los numerales de Church es la posibilidad de definir las operaciones aritméticas de suma, multiplicación y potencia en términos de funciones aplicadas a numerales. La suma se basa en la operación Sucesor (Suc), definida así: (Suc n) := λnfx.f(nfx) Así como la expresión de sucesor de un numeral (Suc n) es relativamente simple, el Predecesor Pn, es decir n−1, es mucho más compleja:
Funciones lógicas

Las funciones lógicas se pueden también definir mediante expresiones lambda. Una función lógica es una función que tiene como parámetros los valores lógicos V (verdadero) o F (falso) y que produce un valor lógico como resultado.

Los valores V y F se definen así: Y las operaciones lógicas se definen de la siguiente manera: Ejemplos: Gracias a las definiciones anteriores de V y F como funciones se puede especificar la condición lógica If-Then-Else, mediante una expresión lambda con 3 variables: b (valor de verdad), t (rama Then) y e (rama Else):
Predicados

Un predicado se define como una función que devuelve un valor de verdad. Un ejemplo de predicado es la función Z, que tiene como parámetro un numeral y que devuelve V si el argumento es el numeral 0, y F si es cualquier otro numeral: En donde hay que tener en cuenta:
Funciones recursivas

Queremos calcular, por ejemplo, la factorial de un número: El problema es que en el cálculo lambda no se permiten funciones recursivas porque las funciones son anónimas y, por lo tanto, no pueden llamarse a sí mismas. Sin embargo, es posible definirlas mediante el combinador Y (también llamado “combinador de punto fijo” o “combinador paradójico”), descubierto por Haskell B. Curry, que se define de la manera siguiente: Aplicando Y a una función R se tiene: Es, decir, YR es igual a la función R aplicada a YR. Aquí aparece la recursividad, pues Mediante Y se pueden codificar funciones recursivas. Por ejemplo, para resolver el problema del factorial, definimos una función g (de manera informal):

g = λf. λn.if n=1 then 1 else n*f(n−1)

g(n) devuelve 1 si n=1 y n*f(n−1) si n≠1.

La función recursiva es g(Yg)n. Por ejemplo, para n=4: La solución formal en cálculo lambda consiste en sustituir las expresiones condicionales y las aritméticas por las correspondientes expresiones lambda basadas en numerales: Por lo tanto, la expresión recursiva es g(Yg)n, con
MENTAL vs. Cálculo Lambda

Paradigmas

Cálculo lambda. MENTAL.
Primitivas

Cálculo lambda. MENTAL.
Nivel de abstracción

Cálculo lambda. MENTAL.
Expresiones

Cálculo lambda. MENTAL.
Variables ligadas y libres

Cálculo lambda. MENTAL.
Aritmética

Cálculo lambda. MENTAL.
Sustitución β

Cálculo lambda. MENTAL.
Conversión α

Cálculo lambda. MENTAL.
Conversión η

La conversión η no es necesaria, ni se necesita ningún formalismo especial, porque a nivel conceptual se ve que las expresiones siguientes (por ejemplo) son iguales, y no solo funciones, sino expresiones en general:
Evaluación parcial

Cálculo lambda. MENTAL.
Recursión

Cálculo lambda. MENTAL.
Computación paralela

Cálculo lambda. MENTAL.
Implementación

Cálculo lambda. MENTAL.
Tipos

Cálculo lambda. MENTAL.
Fundamentación

Cálculo lambda. MENTAL.
Modelo computacional

Cálculo lambda. MENTAL.
Conclusiones

Church, con el cálculo lambda, realizó numerosas aportaciones al campo de la computación, entre ellas: Sin embargo, el cálculo lambda −como la máquina de Turing y la teoría de categorías− es un ejemplo de incumplimiento del principio de la navaja de Einstein: “Hay que hacer todo lo más simple posible, pero no más simple”. Utiliza como único concepto el de expresión funcional, con dos aspectos: definición de una función y aplicación de una función. Esto conduce a graves dificultades expresivas. Todo es una función, lo que produce que los conceptos derivados (números, predicados, valores de verdad, operaciones aritméticas, operaciones lógicas, condiciones, etc.) se expresen de manera compleja y antinatural.



Adenda

Church y sus contribuciones a la ciencia

El cálculo lambda fue desarrollado en los años 1930s por Alonzo Church [1941] para formalizar las funciones computables, es decir, para definirlas de forma precisa: toda función numérica computable es computable mediante el cálculo lambda, utilizando los correspondientes numerales de Church en lugar de los números. El cálculo lambda es un modelo teórico de computación, que tiene una potencia computacional equivalente al de una máquina de Turing.

Cuando se inventó el cálculo lambda, los ordenadores todavía no existían. Sin embargo, se puede considerar el primer lenguaje de programación funcional de la historia. Ha sido el fundamento de muchos lenguajes funcionales, habiendo tenido gran influencia en el diseño de los lenguajes de programación en general.

Lisp fue el primer lenguaje en aplicar el cálculo lambda [McCarthy, 1960], por lo que es el lenguaje funcional más antiguo y popular. Está orientado al cálculo simbólico y se aplica principalmente a temas de inteligencia artificial.

Al Lisp le siguieron, entre otros, Scheme, ML, Miranda y Haskell. De todas formas, lenguajes funcionales “puros” son solo Haskell y Miranda. Y lenguajes híbridos (funcionales con otras características, normalmente imperativas) son Lisp, Scheme y ML.

Las contribuciones principales de Church han sido dos:
  1. La tesis de Church.
    Afirma que toda función numérica efectivamente computable es recursiva y computable por el cálculo lambda. Sustituye de esta forma a la noción informal de “computación”.

    A finales de 1936, Turing, que había estado también trabajando sobre el tema de la computabilidad, publicó su famoso artículo “On computable numbers ...” en el que expone la tesis de que toda función computable es computable por un dispositivo teórico que hoy se conoce como “máquina de Turing”. El propio Turing demostró que ambos modelos computacionales eran equivalentes. La tesis se denomina de Church-Turing, una tesis que conecta los aspectos operacionales, epistémicos y extrínsecos de la aritmética con los aspectos ontológicos, intrínsecos y abstractos. Esta tesis establece también los límites de la computabilidad, pues toda computación está limitada por las primitivas utilizadas (por Church o por Turing).

  2. El teorema de Church.
    Church, estudiando “el problema de decisión de Hilbert” (Entscheidungsproblem) le condujo a lo que se conoce como “teorema de Church”. Este teorema afirma que no existe ningún algoritmo o procedimiento mecánico capaz de decidir si las proposiciones de la aritmética son verdaderas o falsas. Por lo tanto, que no existe una solución general al problema de decisión. Esto equivale a que la lógica de predicados de primer orden es indecidible.

    Church también usó el cálculo lambda para resolver por primera vez el problema de saber si dos expresiones funcionales cualesquiera del cálculo lambda son o no equivalentes. Este problema también es indecidible: no puede ser resuelto por una expresión funcional general del propio cálculo lambda. Esta cuestión fue planteada antes incluso del problema de la parada de una máquina de Turing. Church y Turing estuvieron muy influenciados por el teorema de incompletud de Gödel.
En el año 1990 se celebró un simposio en honor de Church en la State University of New York at Bufalo, por sus contribuciones seminales a los fundamentos de la teoría de la computación.


Los combinadores de punto fijo

Un punto fijo de una función f(x) es un valor v de x tal que f(v) = v. Por ejemplo, 0 y 1 son puntos fijos de f(x) = x2, porque 02 = 0 y 12 = 1. Un punto fijo de una función de orden superior f(g) es otra función h tal que f(h) = h. Como YR = R(YR), entonces YR es un punto fijo de cualquier función R.

El combinador de punto fijo Y de Curry no es el único que existe en el cálculo lambda. De hecho, el cálculo lambda sin tipos posee infinitos combinadores de punto fijo. En 2005, Mayer Goldberg [2005] demostró que el conjunto de combinadores de punto fijo del cálculo lambda es recursivamente numerable. En el cálculo lambda con tipos −más restrictivo a nivel combinatorio− no existe ningún combinador de punto fijo.

El uso de combinadores de punto fijo para la recursión se denomina “recursión anónima”.


Bibliografía